package com.leyou.user.service;

import com.leyou.common.constant.MQConstants;
import com.leyou.common.exception.domain.ExceptionEnum;
import com.leyou.common.exception.domain.LyException;
import com.leyou.common.uploadimgs.LyConstants;
import com.leyou.common.utils.BeanHelper;
import com.leyou.user.domain.User;
import com.leyou.user.dto.UserDTO;
import com.leyou.user.mapper.UserMapper;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.rules.Timeout;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    /**
     * 校验用户名或手机号是否可用
     */
    public Boolean checkUsernameOrPhone(String data, Integer type) {
        User user=new User();
        switch (type){
            case 1:
                user.setUsername(data);
                break;
            case 2:
                user.setPhone(data);
                break;
                default:
                    throw new LyException(ExceptionEnum.INVALID_PARAM_ERROR);

        }
        int count = userMapper.selectCount(user);
        return count!=1;

    }

    /**
     * 发送短信验证码，验证手机短信吗
     */
    public void sendCode(String phone) {
        //生成短信验证码
        String code = RandomStringUtils.randomNumeric(6);
        //向redis中存一份
        redisTemplate.opsForValue().set(LyConstants.CODE_PRE+phone,code,6,TimeUnit.HOURS);
        //给用户发一份
        //封装发送到MQQ队列中的消息
        Map<String,Object>map=new HashMap<>();
        map.put("phone",phone);
        map.put("code",code);
        amqpTemplate.convertAndSend(MQConstants.Exchange.SMS_EXCHANGE_NAME,MQConstants.RoutingKey.VERIFY_CODE_KEY,map);
    }


    /**
     * 完成注册
     */
    public void register(User user, String code) {
        //判断redis总是否有验证码
        Boolean hasKey = redisTemplate.hasKey(LyConstants.CODE_PRE + user.getPhone());
        if (!hasKey){
            throw new LyException(ExceptionEnum.INVALID_VERIFY_CODE);
        }
        //获取redis中的验证码
        String redisCode = redisTemplate.opsForValue().get(LyConstants.CODE_PRE + user.getPhone());
        //比对用户输入的验证码是否和redis中的验证码一致
        if (!StringUtils.equals(redisCode,code)) {
            throw new LyException(ExceptionEnum.INVALID_VERIFY_CODE);


        }
        //密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //入库
        int count = userMapper.insertSelective(user);
        if (count!=1){
            throw  new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

    }

    //在用户微服务中提供根据用户名和密码查询用户的接口提供处理器
    public UserDTO queryUser(String username, String password) {
        //根据用户名查询用户
        User record=new User();
        record.setUsername(username);
        User user = userMapper.selectOne(record);
        if (user==null){
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
        //对比密码是否正确
        boolean isTrue = passwordEncoder.matches(password, user.getPassword());
        if (!isTrue){
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);

        }

        return BeanHelper.copyProperties(user,UserDTO.class);


    }
}
